<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片批量处理工具</title>
    <script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
    <style>
        :root {
            --primary-color: #4361ee;
            --secondary-color: #6c757d;
            --success-color: #06d6a0;
            --warning-color: #ffd166;
            --danger-color: #ef476f;
            --light-bg: #f8f9fa;
            --dark-bg: #212529;
            --border-color: #dee2e6;
            --card-shadow: 0 5px 15px rgba(0,0,0,0.1);
        }
        
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
        }
        
        body {
            background: linear-gradient(135deg, #e0f7fa 0%, #f5f7fa 100%);
            min-height: 100vh;
            padding: 20px;
            color: #333;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
        }
        
        header {
            text-align: center;
            margin-bottom: 30px;
            padding: 20px;
        }
        
        h1 {
            font-size: 2.8rem;
            margin-bottom: 10px;
            background: linear-gradient(90deg, var(--primary-color), var(--success-color));
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            text-shadow: 1px 1px 3px rgba(0,0,0,0.1);
        }
        
        .subtitle {
            font-size: 1.2rem;
            color: var(--secondary-color);
            max-width: 700px;
            margin: 0 auto 25px;
            line-height: 1.6;
        }
        
        .card {
            background: rgba(255, 255, 255, 0.95);
            border-radius: 16px;
            box-shadow: var(--card-shadow);
            padding: 30px;
            margin-bottom: 30px;
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.5);
        }
        
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px rgba(0,0,0,0.15);
        }
        
        .card-title {
            font-size: 1.6rem;
            margin-bottom: 25px;
            color: var(--primary-color);
            display: flex;
            align-items: center;
            gap: 12px;
            position: relative;
            padding-bottom: 12px;
        }
        
        .card-title::after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 0;
            width: 60px;
            height: 4px;
            background: linear-gradient(90deg, var(--primary-color), var(--success-color));
            border-radius: 2px;
        }
        
        .card-title i {
            font-size: 1.8rem;
        }
        
        .upload-area {
            border: 2px dashed var(--border-color);
            border-radius: 12px;
            padding: 40px 30px;
            text-align: center;
            background-color: rgba(67, 97, 238, 0.03);
            cursor: pointer;
            transition: all 0.3s ease;
            margin-bottom: 25px;
            position: relative;
            overflow: hidden;
        }
        
        .upload-area:hover, .upload-area.drag-over {
            border-color: var(--primary-color);
            background-color: rgba(67, 97, 238, 0.08);
        }
        
        .upload-icon {
            font-size: 4rem;
            color: var(--primary-color);
            margin-bottom: 20px;
            opacity: 0.8;
        }
        
        .upload-text {
            font-size: 1.3rem;
            margin-bottom: 15px;
            font-weight: 500;
        }
        
        .upload-hint {
            color: var(--secondary-color);
            font-size: 1rem;
            max-width: 500px;
            margin: 0 auto;
        }
        
        .btn {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            padding: 14px 32px;
            background: linear-gradient(135deg, var(--primary-color), #3a56e6);
            color: white;
            border: none;
            border-radius: 10px;
            font-size: 1.1rem;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            text-align: center;
            box-shadow: 0 5px 15px rgba(67, 97, 238, 0.3);
            gap: 10px;
        }
        
        .btn:hover {
            background: linear-gradient(135deg, #3a56e6, var(--primary-color));
            transform: translateY(-3px);
            box-shadow: 0 8px 20px rgba(67, 97, 238, 0.4);
        }
        
        .btn:active {
            transform: translateY(0);
        }
        
        .btn-lg {
            padding: 16px 40px;
            font-size: 1.2rem;
        }
        
        .btn-secondary {
            background: linear-gradient(135deg, var(--secondary-color), #5a6268);
            box-shadow: 0 5px 15px rgba(108, 117, 125, 0.3);
        }
        
        .btn-secondary:hover {
            background: linear-gradient(135deg, #5a6268, var(--secondary-color));
            box-shadow: 0 8px 20px rgba(108, 117, 125, 0.4);
        }
        
        .btn-success {
            background: linear-gradient(135deg, var(--success-color), #05b48d);
            box-shadow: 0 5px 15px rgba(6, 214, 160, 0.3);
        }
        
        .btn-success:hover {
            background: linear-gradient(135deg, #05b48d, var(--success-color));
            box-shadow: 0 8px 20px rgba(6, 214, 160, 0.4);
        }
        
        .btn-group {
            display: flex;
            gap: 20px;
            margin-top: 30px;
            justify-content: center;
            flex-wrap: wrap;
        }
        
        .progress-container {
            margin-top: 30px;
            background-color: var(--light-bg);
            border-radius: 12px;
            overflow: hidden;
            box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
        }
        
        .progress-bar {
            height: 14px;
            background: linear-gradient(90deg, var(--primary-color), var(--success-color));
            width: 0%;
            transition: width 0.4s ease;
            border-radius: 12px;
        }
        
        .progress-text {
            text-align: center;
            padding: 20px;
            font-size: 1.1rem;
            font-weight: 500;
        }
        
        .result-container {
            margin-top: 35px;
        }
        
        .result-title {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            cursor: pointer;
        }
        
        .result-content {
            max-height: 500px;
            overflow-y: auto;
        }
        
        table {
            width: 100%;
            border-collapse: separate;
            border-spacing: 0;
            border-radius: 12px;
            overflow: hidden;
            box-shadow: 0 2px 10px rgba(0,0,0,0.05);
        }
        
        th, td {
            padding: 16px 20px;
            text-align: left;
            border-bottom: 1px solid var(--border-color);
        }
        
        th {
            background: linear-gradient(to bottom, #f1f3f9, #e9ecef);
            font-weight: 700;
            color: var(--dark-bg);
        }
        
        tr:nth-child(even) {
            background-color: rgba(67, 97, 238, 0.03);
        }
        
        tr:hover {
            background-color: rgba(67, 97, 238, 0.08);
        }
        
        .preview-img {
            width: 70px;
            height: 70px;
            object-fit: cover;
            border-radius: 8px;
            border: 1px solid var(--border-color);
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }
        
        .collapsible {
            max-height: 0;
            overflow: hidden;
            transition: max-height 0.5s ease;
        }
        
        .collapsible.expanded {
            max-height: 500px;
        }
        
        .toggle-icon {
            transition: transform 0.3s ease;
            font-size: 1.5rem;
            color: var(--primary-color);
        }
        
        .toggle-icon.expanded {
            transform: rotate(180deg);
        }
        
        .status-badge {
            display: inline-flex;
            align-items: center;
            padding: 6px 14px;
            border-radius: 20px;
            font-size: 0.9rem;
            font-weight: 600;
            gap: 6px;
        }
        
        .status-badge::before {
            content: '';
            display: block;
            width: 10px;
            height: 10px;
            border-radius: 50%;
        }
        
        .status-pending {
            background-color: #fff3cd;
            color: #856404;
        }
        
        .status-pending::before {
            background-color: #ffc107;
        }
        
        .status-success {
            background-color: #d4edda;
            color: #155724;
        }
        
        .status-success::before {
            background-color: #28a745;
        }
        
        .status-error {
            background-color: #f8d7da;
            color: #721c24;
        }
        
        .status-error::before {
            background-color: #dc3545;
        }
        
        .summary-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 25px;
            margin-top: 35px;
        }
        
        .summary-card {
            background: white;
            border-radius: 14px;
            padding: 25px;
            text-align: center;
            box-shadow: var(--card-shadow);
            border: 1px solid rgba(67, 97, 238, 0.1);
            transition: transform 0.3s ease;
        }
        
        .summary-card:hover {
            transform: translateY(-5px);
        }
        
        .summary-icon {
            font-size: 2.5rem;
            margin-bottom: 15px;
            color: var(--primary-color);
            opacity: 0.8;
        }
        
        .summary-number {
            font-size: 2.8rem;
            font-weight: 700;
            color: var(--primary-color);
            margin: 10px 0;
        }
        
        .summary-label {
            color: var(--secondary-color);
            font-size: 1.1rem;
            font-weight: 500;
        }
        
        .instructions {
            background: linear-gradient(135deg, rgba(67, 97, 238, 0.08), rgba(6, 214, 160, 0.08));
            border-left: 5px solid var(--primary-color);
            padding: 25px;
            border-radius: 0 14px 14px 0;
            margin-bottom: 35px;
            position: relative;
            overflow: hidden;
        }
        
        .instructions::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 5px;
            background: linear-gradient(90deg, var(--primary-color), var(--success-color));
        }
        
        .instructions h3 {
            margin-bottom: 20px;
            color: var(--primary-color);
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        .instructions ol {
            padding-left: 30px;
        }
        
        .instructions li {
            margin-bottom: 15px;
            line-height: 1.7;
            font-size: 1.05rem;
            position: relative;
        }
        
        .instructions li::marker {
            color: var(--primary-color);
            font-weight: bold;
        }
        
        .instructions code {
            background-color: rgba(67, 97, 238, 0.1);
            padding: 3px 8px;
            border-radius: 5px;
            font-family: monospace;
            font-size: 0.95rem;
            color: var(--primary-color);
        }
        
        .file-info {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-top: 20px;
            flex-wrap: wrap;
        }
        
        .file-info-item {
            background: white;
            padding: 15px 25px;
            border-radius: 10px;
            box-shadow: 0 3px 8px rgba(0,0,0,0.08);
            display: flex;
            align-items: center;
            gap: 10px;
            font-weight: 500;
        }
        
        .file-info-icon {
            font-size: 1.5rem;
            color: var(--primary-color);
        }
        
        footer {
            text-align: center;
            margin-top: 40px;
            padding: 20px;
            color: var(--secondary-color);
            font-size: 0.95rem;
        }
        
        @media (max-width: 768px) {
            .btn-group {
                flex-direction: column;
                align-items: center;
            }
            
            .btn {
                width: 100%;
                max-width: 300px;
            }
            
            .summary-grid {
                grid-template-columns: 1fr;
            }
            
            .card {
                padding: 20px;
            }
            
            .upload-area {
                padding: 30px 15px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>图片批量处理工具</h1>
            <p class="subtitle">上传图片文件夹和Excel名称表格，自动完成图片匹配、裁剪、压缩和重命名操作</p>
        </header>
        
        <div class="instructions">
            <h3>📝 使用说明</h3>
            <ol>
                <li>上传包含图片的文件夹（支持JPG/PNG格式）</li>
                <li>上传Excel表格，包含"原名称"和"新名称"两列</li>
                <li>系统会自动将原名称与图片进行模糊匹配</li>
                <li>匹配成功的图片将裁剪为1:1比例，尺寸调整为800×800像素</li>
                <li>图片将压缩到小于1MB大小，并重命名为"新名称-1.jpg"</li>
                <li>同名图片只保留内存占用最大的一张</li>
                <li>点击"开始处理"按钮执行操作，完成后可下载处理好的图片</li>
            </ol>
        </div>
        
        <div class="card">
            <h2 class="card-title">
                <span>步骤1：上传图片文件夹</span>
            </h2>
            <div class="upload-area" id="imageUploadArea">
                <div class="upload-icon">📁</div>
                <p class="upload-text">拖放图片文件夹到此处，或点击选择文件夹</p>
                <p class="upload-hint">支持JPG、PNG格式图片，最多可上传100张</p>
                <input type="file" id="imageInput" webkitdirectory directory multiple accept="image/jpeg, image/png" style="display: none">
            </div>
            
            <h2 class="card-title">
                <span>步骤2：上传名称表格</span>
            </h2>
            <div class="upload-area" id="excelUploadArea">
                <div class="upload-icon">📊</div>
                <p class="upload-text">拖放Excel文件到此处，或点击选择文件</p>
                <p class="upload-hint">表格需包含"原名称"和"新名称"两列（.xls 或 .xlsx格式）</p>
                <input type="file" id="excelInput" accept=".xls, .xlsx" style="display: none">
            </div>
            
            <div class="file-info">
                <div class="file-info-item" id="imageInfo">
                    <span class="file-info-icon">📷</span>
                    <span>已选择: <strong>0</strong> 张图片</span>
                </div>
                <div class="file-info-item" id="excelInfo">
                    <span class="file-info-icon">📝</span>
                    <span>已加载: <strong>0</strong> 个名称</span>
                </div>
            </div>
            
            <div class="btn-group">
                <button class="btn btn-lg" id="processBtn" disabled>
                    <span>🚀 开始处理</span>
                </button>
                <button class="btn btn-lg btn-success" id="downloadBtn" disabled>
                    <span>💾 下载结果</span>
                </button>
                <button class="btn btn-lg btn-secondary" id="resetBtn">
                    <span>🔄 重置</span>
                </button>
            </div>
            
            <div class="progress-container" id="progressContainer" style="display: none;">
                <div class="progress-bar" id="progressBar"></div>
                <div class="progress-text" id="progressText">准备开始处理...</div>
            </div>
        </div>
        
        <div class="card result-container">
            <div class="result-title" id="resultTitle">
                <h2 class="card-title">处理结果</h2>
                <span class="toggle-icon" id="toggleIcon">▼</span>
            </div>
            
            <div class="collapsible" id="resultContent">
                <div class="result-content">
                    <table id="resultTable">
                        <thead>
                            <tr>
                                <th>原名称</th>
                                <th>新名称</th>
                                <th>匹配图片</th>
                                <th>原尺寸</th>
                                <th>处理后</th>
                                <th>状态</th>
                            </tr>
                        </thead>
                        <tbody id="resultBody">
                            <!-- 结果将动态填充 -->
                        </tbody>
                    </table>
                </div>
                
                <div class="summary-grid">
                    <div class="summary-card">
                        <div class="summary-icon">📊</div>
                        <div class="summary-number" id="totalCount">0</div>
                        <div class="summary-label">总处理数量</div>
                    </div>
                    <div class="summary-card">
                        <div class="summary-icon">✅</div>
                        <div class="summary-number" id="successCount">0</div>
                        <div class="summary-label">成功处理</div>
                    </div>
                    <div class="summary-card">
                        <div class="summary-icon">❌</div>
                        <div class="summary-number" id="failedCount">0</div>
                        <div class="summary-label">匹配失败</div>
                    </div>
                    <div class="summary-card">
                        <div class="summary-icon">📉</div>
                        <div class="summary-number" id="sizeReduction">0%</div>
                        <div class="summary-label">大小缩减</div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <footer>
        <p>© 2023 图片批量处理工具 | 基于HTML5技术构建</p>
    </footer>

    <script>
        // 全局变量
        let imageFiles = [];
        let nameMappings = [];
        let processedResults = [];
        let processedImages = {};
        
        // DOM元素
        const imageUploadArea = document.getElementById('imageUploadArea');
        const excelUploadArea = document.getElementById('excelUploadArea');
        const imageInput = document.getElementById('imageInput');
        const excelInput = document.getElementById('excelInput');
        const processBtn = document.getElementById('processBtn');
        const downloadBtn = document.getElementById('downloadBtn');
        const resetBtn = document.getElementById('resetBtn');
        const progressContainer = document.getElementById('progressContainer');
        const progressBar = document.getElementById('progressBar');
        const progressText = document.getElementById('progressText');
        const resultTable = document.getElementById('resultTable');
        const resultBody = document.getElementById('resultBody');
        const totalCount = document.getElementById('totalCount');
        const successCount = document.getElementById('successCount');
        const failedCount = document.getElementById('failedCount');
        const sizeReduction = document.getElementById('sizeReduction');
        const resultTitle = document.getElementById('resultTitle');
        const toggleIcon = document.getElementById('toggleIcon');
        const resultContent = document.getElementById('resultContent');
        const imageInfo = document.getElementById('imageInfo');
        const excelInfo = document.getElementById('excelInfo');

        // 上传区域事件处理
        function setupUploadArea(uploadArea, input) {
            uploadArea.addEventListener('click', () => {
                input.click();
            });

            uploadArea.addEventListener('dragover', (e) => {
                e.preventDefault();
                uploadArea.classList.add('drag-over');
            });

            uploadArea.addEventListener('dragleave', () => {
                uploadArea.classList.remove('drag-over');
            });

            uploadArea.addEventListener('drop', (e) => {
                e.preventDefault();
                uploadArea.classList.remove('drag-over');
                if (input.id === 'imageInput') {
                    const items = e.dataTransfer.items;
                    for (let i = 0; i < items.length; i++) {
                        const item = items[i];
                        if (item.kind === 'file') {
                            const entry = item.webkitGetAsEntry();
                            if (entry && entry.isDirectory) {
                                const reader = entry.createReader();
                                reader.readEntries((entries) => {
                                    entries.forEach((entry) => {
                                        if (entry.isFile) {
                                            entry.file((file) => {
                                                if (file.type === 'image/jpeg' || file.type === 'image/png') {
                                                    imageFiles.push(file);
                                                }
                                            });
                                        }
                                    });
                                    updateImageInfo();
                                });
                            }
                        }
                    }
                } else {
                    const files = e.dataTransfer.files;
                    if (files.length > 0) {
                        const file = files[0];
                        const reader = new FileReader();
                        reader.onload = (e) => {
                            const data = new Uint8Array(e.target.result);
                            const workbook = XLSX.read(data, { type: 'array' });
                            const firstSheetName = workbook.SheetNames[0];
                            const worksheet = workbook.Sheets[firstSheetName];
                            nameMappings = XLSX.utils.sheet_to_json(worksheet);
                            updateExcelInfo();
                        };
                        reader.readAsArrayBuffer(file);
                    }
                }
            });

            input.addEventListener('change', () => {
                if (input.id === 'imageInput') {
                    const files = input.files;
                    for (let i = 0; i < files.length; i++) {
                        const file = files[i];
                        if (file.type === 'image/jpeg' || file.type === 'image/png') {
                            imageFiles.push(file);
                        }
                    }
                    updateImageInfo();
                } else {
                    const files = input.files;
                    if (files.length > 0) {
                        const file = files[0];
                        const reader = new FileReader();
                        reader.onload = (e) => {
                            const data = new Uint8Array(e.target.result);
                            const workbook = XLSX.read(data, { type: 'array' });
                            const firstSheetName = workbook.SheetNames[0];
                            const worksheet = workbook.Sheets[firstSheetName];
                            nameMappings = XLSX.utils.sheet_to_json(worksheet);
                            updateExcelInfo();
                        };
                        reader.readAsArrayBuffer(file);
                    }
                }
            });
        }

        // 更新图片信息
        function updateImageInfo() {
            const imageCount = imageFiles.length;
            imageInfo.querySelector('strong').textContent = imageCount;
            checkProcessButtonStatus();
        }

        // 更新Excel信息
        function updateExcelInfo() {
            const nameCount = nameMappings.length;
            excelInfo.querySelector('strong').textContent = nameCount;
            checkProcessButtonStatus();
        }

        // 检查处理按钮状态
        function checkProcessButtonStatus() {
            if (imageFiles.length > 0 && nameMappings.length > 0) {
                processBtn.disabled = false;
            } else {
                processBtn.disabled = true;
            }
        }

        // 处理图片
        async function processImages() {
            progressContainer.style.display = 'block';
            processBtn.disabled = true;
            downloadBtn.disabled = true;

            let totalOriginalSize = 0;
            let totalProcessedSize = 0;
            let success = 0;
            let fail = 0;

            for (let i = 0; i < nameMappings.length; i++) {
                const mapping = nameMappings[i];
                const originalName = mapping['原名称'];
                const newName = mapping['新名称'];

                let matchedImage = null;
                for (let j = 0; j < imageFiles.length; j++) {
                    const image = imageFiles[j];
                    if (image.name.includes(originalName)) {
                        if (!matchedImage || image.size > matchedImage.size) {
                            matchedImage = image;
                        }
                    }
                }

                if (matchedImage) {
                    const originalSize = matchedImage.size;
                    totalOriginalSize += originalSize;

                    // 实际处理图片
                    const processedImage = await processSingleImage(matchedImage);
                    const processedSize = processedImage.size;
                    totalProcessedSize += processedSize;

                    // 保存处理后的图片
                    const outputFileName = `${newName}-1.jpg`;
                    processedImages[outputFileName] = processedImage;

                    // 创建图片预览URL
                    const previewUrl = URL.createObjectURL(processedImage);

                    processedResults.push({
                        originalName: originalName,
                        newName: newName,
                        originalSize: formatSize(originalSize),
                        processedSize: formatSize(processedSize),
                        status: '成功',
                        previewUrl: previewUrl
                    });
                    success++;
                } else {
                    processedResults.push({
                        originalName: originalName,
                        newName: newName,
                        originalSize: '无',
                        processedSize: '无',
                        status: '失败',
                        previewUrl: null
                    });
                    fail++;
                }

                const progress = ((i + 1) / nameMappings.length) * 100;
                progressBar.style.width = `${progress}%`;
                progressText.textContent = `处理中: ${i + 1}/${nameMappings.length}`;
            }

            const reduction = totalOriginalSize > 0 ? ((totalOriginalSize - totalProcessedSize) / totalOriginalSize) * 100 : 0;
            sizeReduction.textContent = `${reduction.toFixed(2)}%`;
            totalCount.textContent = nameMappings.length;
            successCount.textContent = success;
            failedCount.textContent = fail;

            populateResultTable();
            downloadBtn.disabled = false;
            progressText.textContent = '处理完成';
        }

        // 处理单张图片 - 实际实现裁剪、压缩功能
        function processSingleImage(image) {
            return new Promise((resolve) => {
                const img = new Image();
                img.src = URL.createObjectURL(image);
                
                img.onload = () => {
                    // 创建canvas进行图片处理
                    const canvas = document.createElement('canvas');
                    const ctx = canvas.getContext('2d');
                    
                    // 确定图片的尺寸，裁剪为1:1比例
                    const width = img.width;
                    const height = img.height;
                    
                    let cropSize, offsetX, offsetY;
                    
                    if (width > height) {
                        // 宽图，以高度为基准裁剪
                        cropSize = height;
                        offsetX = (width - height) / 2;
                        offsetY = 0;
                    } else {
                        // 高图，以宽度为基准裁剪
                        cropSize = width;
                        offsetX = 0;
                        offsetY = (height - width) / 2;
                    }
                    
                    // 设置canvas尺寸为800x800
                    canvas.width = 800;
                    canvas.height = 800;
                    
                    // 将裁剪后的图片绘制到canvas上
                    ctx.drawImage(img, offsetX, offsetY, cropSize, cropSize, 0, 0, 800, 800);
                    
                    // 压缩图片 - 尝试不同的质量设置，直到文件大小小于1MB
                    let quality = 0.9;
                    let blob = null;
                    
                    const checkSize = () => {
                        canvas.toBlob((resultBlob) => {
                            blob = resultBlob;
                            
                            // 如果文件大小仍然大于1MB，继续降低质量
                            if (blob.size > 1024 * 1024 && quality > 0.1) {
                                quality -= 0.1;
                                checkSize();
                            } else {
                                // 释放URL对象
                                URL.revokeObjectURL(img.src);
                                
                                // 创建File对象，保持原始文件名的扩展名
                                const fileName = image.name.replace(/\.[^\.]+$/, '') + '.jpg';
                                const processedFile = new File([blob], fileName, {
                                    type: 'image/jpeg',
                                    lastModified: Date.now()
                                });
                                
                                resolve(processedFile);
                            }
                        }, 'image/jpeg', quality);
                    };
                    
                    checkSize();
                };
                
                img.onerror = () => {
                    // 释放URL对象
                    URL.revokeObjectURL(img.src);
                    
                    // 出错时返回原始图片
                    resolve(image);
                };
            });
        }

        // 格式化文件大小
        function formatSize(bytes) {
            if (bytes < 1024) {
                return `${bytes} B`;
            } else if (bytes < 1024 * 1024) {
                return `${(bytes / 1024).toFixed(2)} KB`;
            } else {
                return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
            }
        }

        // 填充结果表格
        function populateResultTable() {
            resultBody.innerHTML = '';
            processedResults.forEach((result) => {
                const row = document.createElement('tr');
                const previewCell = document.createElement('td');
                
                if (result.previewUrl) {
                    const img = document.createElement('img');
                    img.src = result.previewUrl;
                    img.alt = result.originalName;
                    img.className = 'preview-img';
                    previewCell.appendChild(img);
                }
                
                row.innerHTML = `
                    <td>${result.originalName}</td>
                    <td>${result.newName}</td>
                    <td></td>
                    <td>${result.originalSize}</td>
                    <td>${result.processedSize}</td>
                    <td><span class="status-badge ${result.status === '成功' ? 'status-success' : 'status-error'}">${result.status}</span></td>
                `;
                
                // 插入预览图片单元格
                row.insertBefore(previewCell, row.children[2]);
                
                resultBody.appendChild(row);
            });
        }

        // 下载结果 - 使用JSZip创建ZIP文件
        async function downloadResults() {
            if (Object.keys(processedImages).length === 0) {
                alert('没有可下载的图片');
                return;
            }
            
            // 创建ZIP文件
            const zip = new JSZip();
            
            // 添加处理后的图片到ZIP
            for (const [fileName, file] of Object.entries(processedImages)) {
                zip.file(fileName, file);
            }
            
            // 生成下载进度
            progressContainer.style.display = 'block';
            progressBar.style.width = '0%';
            progressText.textContent = '正在准备下载...';
            
            // 生成ZIP文件
            zip.generateAsync({ 
                type: 'blob',
                compression: 'DEFLATE',
                compressionOptions: {
                    level: 6
                }
            }, (metadata) => {
                // 更新进度
                const percent = metadata.percent.toFixed(0);
                progressBar.style.width = `${percent}%`;
                progressText.textContent = `准备下载: ${percent}%`;
            }).then((content) => {
                // 创建下载链接
                const url = URL.createObjectURL(content);
                const a = document.createElement('a');
                a.href = url;
                a.download = 'processed_images.zip';
                
                // 模拟点击下载
                document.body.appendChild(a);
                a.click();
                
                // 清理
                document.body.removeChild(a);
                URL.revokeObjectURL(url);
                
                // 隐藏进度条
                setTimeout(() => {
                    progressContainer.style.display = 'none';
                }, 1000);
            });
        }

        // 重置
        function reset() {
            imageFiles = [];
            nameMappings = [];
            processedResults = [];
            processedImages = {};

            imageInfo.querySelector('strong').textContent = 0;
            excelInfo.querySelector('strong').textContent = 0;
            processBtn.disabled = true;
            downloadBtn.disabled = true;
            progressContainer.style.display = 'none';
            progressBar.style.width = '0%';
            progressText.textContent = '准备开始处理...';
            resultBody.innerHTML = '';
            totalCount.textContent = 0;
            successCount.textContent = 0;
            failedCount.textContent = 0;
            sizeReduction.textContent = '0%';
        }

        // 展开/收起结果
        function toggleResult() {
            resultContent.classList.toggle('expanded');
            toggleIcon.classList.toggle('expanded');
        }

        // 初始化
        setupUploadArea(imageUploadArea, imageInput);
        setupUploadArea(excelUploadArea, excelInput);
        processBtn.addEventListener('click', processImages);
        downloadBtn.addEventListener('click', downloadResults);
        resetBtn.addEventListener('click', reset);
        resultTitle.addEventListener('click', toggleResult);
    </script>
</body>
</html>
